/*
 * Copyright 2007 - The JDPF Project Team (http://www.jdpf.org) 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package org.jdpf.core.plugins.blocks.transitions;

import java.util.List;

import org.jdpf.core.kernel.elements.AbstractTransition;
import org.jdpf.core.kernel.elements.InputArc;
import org.jdpf.core.kernel.elements.OutputArc;
import org.jdpf.core.kernel.elements.Token;
import org.jdpf.core.kernel.logging.ILogger;
import org.jdpf.core.kernel.logging.LoggerFactory;

public class AggregatorTransition extends AbstractTransition {
	/**
	 * Logger for this class
	 */
    	private static final ILogger logger = LoggerFactory.getDefault().getLogger();
	
	/**
	 * @param id
	 * @param name
	 */
	public AggregatorTransition(String id, String name) {
		super(id, name, OccurrenceConstraints.TWO_TO_ONE);
	}
	
	/**
	 * Add a new output arc only if there isn't anyone available yet 
	 * @throws RuntimeException 
	 */
	public AbstractTransition addOutputArc(final OutputArc outputArc){
		
		if (super.outputs.size() > 0)
			throw new RuntimeException(
					"Too many output arcs for the Aggregator Transition with id: "
							+ super.getId() + " and name: " + super.getName());

		super.outputs.add(outputArc);
		return this;		
	}
	
	/**
	 * Check if all input arcs are enabled
	 */
	public boolean isEnabled(){
		int count=0;
		for(InputArc inputArc:super.inputs){
			if(inputArc.isEnabled()) count++;
		}
		return super.inputs.size()==count;
	}
	
	/**
	 * Fire the transition.
	 * It takes a token from each place associated to an input arc, elaborate them and at the 
	 * end it creates a new token as the result of the elaboration process to send on the output
	 * arc to a place.
	 */
	public void fire(boolean withAction){
		List<Token> list=getInputs();
		Token token=process(list);
		setOutputs(token);
		removeInputTokens();
	}
	
	public Token process(List<Token> list){
		logger.log("Firing transition "+this.getId());
		return new Token();
	}

}
